#region license
/*
 * Copyright (C) 2007 CchenSoft.com
 * 
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License 2.1 or later, as
 * published by the Free Software Foundation. See the included License.txt
 * or http://www.gnu.org/copyleft/lesser.html for details.
 * 
 * Author: Billy Zhang
 */
#endregion

using System.Collections;
using System.Xml;
using System.Collections.Generic;

namespace CchenSoft.Workflow.Loader
{
    public class RestrictionDescriptor : AbstractDescriptor, IValidatable
    {
        //~ Instance fields ////////////////////////////////////////////////////////

        protected List<ConditionsDescriptor> conditions = new List<ConditionsDescriptor>();

        //~ Constructors ///////////////////////////////////////////////////////////

        public RestrictionDescriptor()
        {
        }

        public RestrictionDescriptor(XmlElement restriction)
        {
            Init(restriction);
        }

        //~ Methods ////////////////////////////////////////////////////////////////

        /**
         * @deprecated A restrict-to can only have one conditions element,
         * please use {@link #getConditionsDescriptor()} instead.
         */
        public IList<ConditionsDescriptor> Conditions
        {
            get { return conditions; }
        }

        public ConditionsDescriptor ConditionsDescriptor
        {
            get
            {
                if (conditions.Count == 0)
                {
                    return null;
                }

                return (ConditionsDescriptor)conditions[0];
            }
            set
            {
                if (conditions.Count == 1)
                {
                    conditions.Insert(0, value);
                }
                else
                {
                    conditions.Add(value);
                }
            }
        }

        public void Validate()
        {
            if (conditions.Count > 1)
            {
                throw new InvalidWorkflowDescriptorException("A restrict-to element can only have one conditions child element");
            }

            ValidationHelper.Validate((ICollection<IValidatable>)conditions);
        }

        public override void WriteXML(XmlTextWriter writer, int indent)
        {
            IList<BaseConditionDescriptor> list = ConditionsDescriptor.Conditions;

            if (list.Count == 0)
            {
                return;
            }

            XMLUtil.printIndent(writer, indent++);
            writer.WriteStartElement("restrict-to");
            ConditionsDescriptor.WriteXML(writer, indent);
            XMLUtil.printIndent(writer, --indent);
            writer.WriteEndElement(); // ("</restrict-to>");
        }

        protected void Init(XmlElement restriction)
        {
            // set up condition - OPTIONAL
            XmlNodeList conditionNodes = restriction.SelectNodes("conditions");
            int length = conditionNodes.Count;

            for (int i = 0; i < length; i++)
            {
                XmlElement condition = (XmlElement)conditionNodes[i];
                ConditionsDescriptor conditionDescriptor = DescriptorFactory.GetFactory().CreateConditionsDescriptor(condition);
                conditionDescriptor.Parent = this;
                this.conditions.Add(conditionDescriptor);
            }
        }
    }
}
